﻿using DH.Core;
using DH.Core.Exceptions;
using DH.Core.Extensions;
using DH.Core.MapperHelper;
using DH.Data;
using DH.Data.ORM.EF;
using DH.Data.ORM.EF.Extensions;
using DH.Entity;
using DH.Service.ViewModels;
using DH.Service.ViewModels.Dto;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DH.Service.Domain.User
{
  public interface IUserService<T, TKey> : IBaseService
    {
       
    }
   public class UserService:BaseService<UserEntity,string>
    {
        protected IServiceCollection _serviceCollection;
        OrganizeService _organizeService;

        public UserService(IServiceCollection service, DbCoreUnitOfWork unitOfWork) : base(service,unitOfWork)
        {
            this._serviceCollection = service;
            this._organizeService = this._serviceCollection.BuildServiceProvider().GetService<OrganizeService>();
        }

            

        public bool CheckUser(string userName,string userPass,out  UserEntity userModel,out string msg)
        {

            userName.NotNullOrEmpty();
            userPass.NotNullOrEmpty();

            userModel = null;
            msg = "";

            var userInfo = _repository.Set.Where(c => c.DH_DeleteMark == false && c.DH_Account == userName).FirstOrDefault();

            //var res = _repository.Context.Database.SqlQuery<UserEntity>("");

            if (userInfo==null)
            {
                msg = "用户不存在";
                return false;
            }
            if (userInfo.DH_EnableMark==false)
            {
                msg = "用户已锁定,请联系管理员";
                return false;
            }
            ///todo: 密码加密，待完成
            if (userInfo.DH_UserPass != userPass)
            {
                msg = "密码错误";
                return false;
            }

            userModel = userInfo;
            
            return true;
        }

        public PagedData<UserEntity> GetList(string key, string orgParentId, Pagination page)
        {
            var userQuery = GetAllSync() as IQueryable<UserEntity>;
            userQuery = userQuery.Where(c => c.Id != Guid.Empty.ToString() && c.DH_DeleteMark == false);
            if (!string.IsNullOrWhiteSpace(key))
            {
                userQuery = userQuery.Where(c => (c.DH_Account.Contains(key)  || c.DH_NickName.Contains(key)));
            }
            if (!string.IsNullOrEmpty(orgParentId))
            {
                var orgParent = _organizeService.GetSync(orgParentId);
                if (orgParent != null)
                {
                    userQuery = userQuery.Where(c => c.IndexId.Contains(orgParent.IndexId));
                }

            }
            var tableEntityList = userQuery.OrderBy(c => c.CreatedOn).TakePageData(page);
            return tableEntityList;
            
        }
        public UserEntity Add(UserViewModel userView)
        {
            UserEntity model;
            model = DHMapper.Map<UserViewModel, UserEntity>(userView);
            model.Id = Guid.NewGuid().ToString();
            model.DH_HeadIcon = "/content/img/samples/mrhua.jpg";
            model.DH_IsAdministrator = false;
            model.CreatedOn =DateTimeOffset.Now;
            model.UpdatedOn = DateTimeOffset.Now;
            model.DH_EnableMark = true;
            model.DH_DeleteMark = false;
            model.DH_UserPass = "123456";
            model.DH_OrganizeId = userView.OrganizationIds;
            model.OrgName = userView.Organizations;

            //方案一：把用户归入组织，一样分配排序id(IndexId)
            //此组织支持个人归属多个组织
            var sortIndex = 0;
            model.IndexId = this._organizeService.GetNodesInParents(model.DH_OrganizeId);
            model.SortIndex = sortIndex;

            InsertSync(model);

            return model;
        }
        public UserEntity Edit(UserViewModel viewModel) {
            var oldObj = GetSync(viewModel.Id);
            var oldOrgId = oldObj.DH_OrganizeId;

            var entity = DHMapper.Map<UserViewModel, UserEntity>(viewModel, oldObj);

            //有没有更改组织
            //若有更改组织，重新分配排序Id
            if (oldOrgId!=entity.DH_OrganizeId)
            {
                entity.IndexId = this._organizeService.GetNodesInParents(entity.DH_OrganizeId);
            }
            

            UpdateSync(entity);

            return entity;
            
        }
        public void Delete(string[] ids)
        {
            var models = GetByQuery(c => ids.Contains(c.Id));
            DeleteSync(models);
        }

        public bool EnabledUser(string id) {

            var userObj = GetSync(id);
            if (userObj != null)
            {
                userObj.DH_EnableMark = true;
                UpdateSync(userObj);
                return true;
            }
            else {
                return false;
            }
        }

        public bool DisabledUser(string id) {
            var userObj = GetSync(id);
            if (userObj != null)
            {
                userObj.DH_EnableMark = false;
                UpdateSync(userObj);
                return true;
            }
            else
            {
                return false;
            }
        }

        public List<UserDto> GetFullPathUser()
        {
            var userDtos = new List<UserDto>();
            var fullPathOrg = _organizeService.GetFullPathOrg();

            var res = GetByQuery(c => c.DH_EnableMark == true && c.DH_DeleteMark == false);

            foreach (var r in res)
            {
                char[] splits = {','};
                var orgs = r.DH_OrganizeId.Split(splits, StringSplitOptions.RemoveEmptyEntries);
                foreach (var org in orgs)
                {
                    var userOrgInfo = fullPathOrg.Find(c=>c.Id==org);

                    var userDtoModel = new UserDto();
                    userDtoModel.UserId = r.Id;
                    userDtoModel.Name = r.DH_RealName;
                    if (userOrgInfo!=null)
                    {
                        userDtoModel.OrgName = userOrgInfo.Name;
                        userDtoModel.OrgFullName = userOrgInfo.FullName;
                    }

                    userDtos.Add(userDtoModel);
                }
            }

            return userDtos;
        }

        #region 异步操作
        public async  Task<PagedData<UserEntity>> GetListAsync(string key, string orgParentId, Pagination page)
        {
            var userQuery = (await GetAllAsync()) as IQueryable<UserEntity>;
            userQuery = userQuery.Where(c => c.Id != Guid.Empty.ToString() && c.DH_DeleteMark == false);
            if (!string.IsNullOrWhiteSpace(key))
            {
                userQuery = userQuery.Where(c => (c.DH_Account.Contains(key) || c.DH_NickName.Contains(key)));
            }
            if (!string.IsNullOrEmpty(orgParentId))
            {
                var orgParent = await _organizeService.GetAsync(orgParentId);
                if (orgParent != null)
                {
                    userQuery = userQuery.Where(c => c.IndexId.StartsWith(orgParent.IndexId));
                }

            }
            var tableEntityList = userQuery.OrderBy(c => c.CreatedOn).TakePageData(page);
            return tableEntityList;

        }
        public async Task<UserEntity> AddAsync(UserViewModel userView)
        {
            UserEntity model;
            model = DHMapper.Map<UserViewModel, UserEntity>(userView);
            model.Id = Guid.NewGuid().ToString();
            model.DH_HeadIcon = "/content/img/samples/mrhua.jpg";
            model.DH_IsAdministrator = false;
            model.CreatedOn = DateTimeOffset.Now;
            model.UpdatedOn = DateTimeOffset.Now;
            model.DH_EnableMark = true;
            model.DH_DeleteMark = false;
            model.DH_UserPass = "123456";
            model.DH_OrganizeId = userView.OrganizationIds;
            model.OrgName = userView.Organizations;

            //方案一：把用户归入组织，一样分配排序id(IndexId)
            //此组织支持个人归属多个组织
            var sortIndex = 0;
            model.IndexId = this._organizeService.GetNodesInParents(model.DH_OrganizeId);
            model.SortIndex = sortIndex;

            await InsertAsync(model);

            return model;
        }
        public async Task<UserEntity> EditAsync(UserViewModel viewModel)
        {
            var oldObj =await GetAsync(viewModel.Id);
            var oldOrgId = oldObj.DH_OrganizeId;

            var entity = DHMapper.Map<UserViewModel, UserEntity>(viewModel, oldObj);

            //有没有更改组织
            //若有更改组织，重新分配排序Id
            if (oldOrgId != entity.DH_OrganizeId)
            {
                entity.IndexId = this._organizeService.GetNodesInParents(entity.DH_OrganizeId);
            }


            await UpdateAsync(entity);

            return entity;

        }
        public async Task DeleteAsync(string[] ids)
        {
            var models =await GetByQueryAsync(c => ids.Contains(c.Id));
            await DeleteAsync(models);
        }

        public async  Task<bool> EnabledUserAsync(string id)
        {

            var userObj =await GetAsync(id);
            if (userObj != null)
            {
                userObj.DH_EnableMark = true;
                await UpdateAsync(userObj);
                return true;
            }
            else
            {
                return false;
            }
        }

        public async Task<bool> DisabledUserAsync(string id)
        {
            var userObj =await  GetAsync(id);
            if (userObj != null)
            {
                userObj.DH_EnableMark = false;
                await UpdateAsync(userObj);
                return true;
            }
            else
            {
                return false;
            }
        }

        public async Task<List<UserDto>> GetFullPathUserAsync()
        {
            var userDtos = new List<UserDto>();
            var fullPathOrg = _organizeService.GetFullPathOrg();

            var res = await GetByQueryAsync(c => c.DH_EnableMark == true && c.DH_DeleteMark == false);

            foreach (var r in res)
            {
                char[] splits = { ',' };
                var orgs = r.DH_OrganizeId.Split(splits, StringSplitOptions.RemoveEmptyEntries);
                foreach (var org in orgs)
                {
                    var userOrgInfo = fullPathOrg.Find(c => c.Id == org);

                    var userDtoModel = new UserDto();
                    userDtoModel.UserId = r.Id;
                    userDtoModel.Name = r.DH_RealName;
                    if (userOrgInfo != null)
                    {
                        userDtoModel.OrgName = userOrgInfo.Name;
                        userDtoModel.OrgFullName = userOrgInfo.FullName;
                    }

                    userDtos.Add(userDtoModel);
                }
            }

            return userDtos;
        }

        public async Task<UserEntity> GetUserInfoAsync(string userId)
        {
            var res = await GetByQueryAsync(c=>c.DH_EnableMark==true&&c.DH_DeleteMark==false&&c.DH_Account==userId);
            if (res.Any())
            {
                return res.First();
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 新增或编辑用户检查userId 是否已存在
        /// </summary>
        /// <param name="userId">useid</param>
        /// <param name="id">id主键</param>
        /// <returns></returns>
        public async Task<bool> CheckExistUserIdAsync(string userId,string id)
        {
            var res = false;
            if (!string.IsNullOrEmpty(id))
            {
                var resQuery = await GetByQueryAsync(c => c.DH_Account == userId && c.Id != id);
                if (resQuery.Any())
                {
                    res = true;
                }
            }
            else
            {
                var resQuery = await GetByQueryAsync(c => c.DH_Account == userId);
                if (resQuery.Any())
                {
                    res = true;
                }
            }
            return res;

        }

        public async Task<UserEntity> UpdateUserInfoAsync(string userId,string userNickName="", string userSign="", string userPhone="", string email="",string userImg="")
        {
            var res = (await GetByQueryAsync(c => c.DH_EnableMark == true && c.DH_DeleteMark == false && c.DH_Account == userId)).FirstOrDefault();
            if (res!=null)
            {
                userNickName= userNickName ?? "";
                userSign = userSign ?? "";
                userPhone= userPhone ?? "";
                email= email ?? "";
                userImg=userImg ?? "";

                res.DH_NickName = userNickName.Trim();
                res.DH_Signature = userSign.Trim();
                res.DH_MobilePhone = userPhone.Trim();
                res.DH_Email = email.Trim();
                res.DH_HeadIcon = userImg.Trim();

                await UpdateAsync(res);
                return res;
            }
            else
            {
                return null;
            }
        }
 
        #endregion
    }
}
